#ifndef __UART_FIFO_H__
#define __UART_FIFO_H__

#include <stdint.h>
#include <stdbool.h>

typedef struct _fifo_t{
    uint8_t* buf;                     // 缓存数组(队列形式组织)
    uint16_t buf_len;                 // 数组长度
	volatile uint16_t front;          // 队头位置(非中断上下文修改)
    volatile uint16_t rear;           // 队尾位置(中断里设置)
}fifo_t;

static inline bool fifo_empty(fifo_t* q)
{
    return q->rear == q->front;
}

static inline bool fifo_full(fifo_t* q)
{   
    return (q->rear + 1) % q->buf_len == q->front;
}

static inline int fifo_size(fifo_t* q)
{   
    return q->buf_len;
}

static inline int fifo_cnt(fifo_t* q)    
{
    return (q->rear - q->front + q->buf_len) % q->buf_len;
}

static inline int fifo_remain(fifo_t* q) 
{
    return q->buf_len - fifo_cnt(q) - 1; /* 约定队头在队尾的下一个位置为满, 因此有效长度为len-1 */
}


static inline bool fifo_pop(fifo_t* q, uint8_t *elem)
{
	if(fifo_empty(q)){
		return false;
    }
	
    *elem = q->buf[q->front];
    q->front = (q->front + 1) % q->buf_len;
    return true;
}

static inline bool fifo_push(fifo_t* q, uint8_t elem)
{
    if(fifo_full(q)){
        return false;
    }
	
	q->buf[q->rear] = elem;
	q->rear = (q->rear +1) % q->buf_len;
	return true;
}

#endif